iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
自我挑戰組

30天用Python打造你的數位金融實力:從零開始的FinTech入門筆記系列 第 19

用 Python 做一個「迷你行動支付錢包」:儲值、付款連結、交易紀錄

  • 分享至 

  • xImage
  •  

今日要點

  • 把抽象的「行動支付」拆成三步:儲值 → 產生付款連結 → 處理扣款與記錄
  • 不碰艱深名詞,也不接外部 API;先把流程概念建立起來,之後再逐步進階(例如加入安全簽章或 Flask API)。

你會完成的功能

  1. 建立兩個錢包(Alice、Bob)並儲值
  2. Alice 產生一個「付款連結」(可把它想像成 QR 內的文字)
  3. 系統解析連結、檢查餘額,完成扣款與轉帳
  4. 輸出交易紀錄 tx_log.csv,方便後續做報表

Python 小實作

import uuid, time, csv
import urllib.parse as up

# === 1) 簡單的錢包狀態 ===
balances = {"Alice": 0.0, "Bob": 0.0}
tx_log = []  # 紀錄每一筆交易

def top_up(user: str, amount: float):
    balances[user] = balances.get(user, 0.0) + float(amount)
    print(f"🎉 {user} 儲值 {amount:.2f},目前餘額:{balances[user]:.2f}")

# === 2) 產生「付款連結」(可想像成 QR 內容) ===
def make_paylink(payer: str, payee: str, amount: float, ccy="TWD", memo=""):
    params = {
        "from": payer,
        "to": payee,
        "amt": f"{float(amount):.2f}",
        "ccy": ccy,
        "memo": memo,
        "ts": str(int(time.time())),
        "id": str(uuid.uuid4()),
    }
    link = "pay://transfer?" + up.urlencode(params)
    return link

# === 3) 解析並處理付款連結 ===
def process_paylink(link: str):
    # 取出 query string 並解析
    try:
        qs = link.split("?", 1)[1]
    except IndexError:
        raise ValueError("連結格式錯誤,缺少參數。")

    data = dict(up.parse_qsl(qs))
    payer = data.get("from"); payee = data.get("to")
    amount = float(data.get("amt", 0.0))
    ccy = data.get("ccy", "TWD"); memo = data.get("memo", "")
    tx_id = data.get("id", str(uuid.uuid4())); ts = int(data.get("ts", time.time()))

    status = "SUCCESS"
    reason = ""
    # 簡單餘額檢查
    if balances.get(payer, 0.0) < amount:
        status = "FAIL_NO_BALANCE"
        reason = "餘額不足"
    else:
        balances[payer] -= amount
        balances[payee] = balances.get(payee, 0.0) + amount

    # 紀錄交易
    tx_log.append({
        "id": tx_id, "ts": ts, "from": payer, "to": payee,
        "amount": amount, "ccy": ccy, "memo": memo,
        "status": status, "reason": reason
    })
    return status, reason

# === 4) 情境示範:Alice 付午餐錢給 Bob ===
top_up("Alice", 500)                 # Alice 先儲值
print("目前餘額:", balances)

link = make_paylink("Alice", "Bob", 120, ccy="TWD", memo="午餐AA")
print("\n📎 付款連結內容(可用於 QR):\n", link)

status, reason = process_paylink(link)
print("\n付款結果:", status, reason)
print("交易後餘額:", balances)

# === 5) 另存交易紀錄,方便後續做報表 ===
with open("tx_log.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["id","ts","from","to","amount","ccy","memo","status","reason"])
    writer.writeheader()
    writer.writerows(tx_log)

print("\n✅ 交易紀錄已輸出:tx_log.csv")

你會在終端機看到

  • 儲值成功提示與當前餘額
  • 一段 pay://transfer?... 的「付款連結」字串(真實場景可放進 QR)
  • 付款成功或失敗(例如餘額不足)的結果
  • 檔案 tx_log.csv,裡面有每筆交易的 from/to/金額/狀態

重點回顧

  • 支付流程其實可以很直覺:餘額管理 + 付款請求 + 扣款記錄。
  • 我們用「連結」代表 QR 內容,成功地把生活經驗(掃碼付款)轉成程式流程。
  • 這份程式是你之後做「迷你收款系統」的地基:
    • 加上 安全簽章(HMAC) → 防竄改
    • 用 Flask 做兩個 API:/make_link、/pay
    • 每天把 tx_log.csv 轉成報表寄給自己(自動化!)

上一篇
從 QR Code 開始認識數位支付
下一篇
跨境支付換匯小工具:一眼看懂匯率、價差與手續費
系列文
30天用Python打造你的數位金融實力:從零開始的FinTech入門筆記29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言